from queue import Queue
import threading
import socket
import datetime
from time import strftime


class network_UDP(object):
    def __init__(self, port, send_port):
        '''
        This is UDP client!
        :param port: HOST port
        :param send_port: send port
        '''
        self.Q_1 = Queue(5)
        self.Q_2 = Queue(1)

        self.self_ip = socket.gethostbyname(socket.gethostname())
        self.port = port
        self.send_port = send_port
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.udp_socket.bind((self.self_ip, self.send_port))
        self.get_mes_Thread = threading.Thread(target=self.netrecv, args=())
        self.get_mes_Thread.start()

    def netrecv(self):

        while True:
            try:
                rev_mes, recv_address = self.udp_socket.recvfrom(10240)
                if rev_mes:
                    # data = rev_mes
                    data = rev_mes.decode('utf-8')
                    self.Q_1.put((data, recv_address))
            except:
                break
        print("通讯结束:", self.self_ip, ':', self.send_port)

    def netsend(self, data, server_address):
        self.udp_socket.sendto(data.encode('utf-8'), (server_address, self.port))
        return len(data)

    def stop_Run(self):
        while not self.Q_1.empty():
            print(self.Q_1.get())
        self.udp_socket.close()
        self.Q_1.put('exit')


class network_TCP_server(object):
    def __init__(self, port, send_port):
        self.Q_1 = Queue(5)
        self.Q_2 = Queue(1)
        self.port = port
        self.send_port = send_port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((self.get_ip_port(), send_port))
        self.server_socket.listen(5)
        # self.server_socket.settimeout(5)
        self.Client_Thread = threading.Thread(target=self.Client, args=())
        self.Client_Thread.start()

    def get_ip_port(self):
        self.self_ip = socket.gethostbyname(socket.gethostname())
        print(self.self_ip)
        return self.self_ip

    def Client(self):
        while True:
            try:
                self.client_socket, self.client_address = self.server_socket.accept()
                print(f"Accepted connection from {self.client_address}")
                self.Q_2.put(True)
                self.netrecv_th()
            except:
                break

    def netrecv_th(self):
        self.netrecv_Thread = threading.Thread(target=self.netrecv, args=())
        self.netrecv_Thread.start()

    def netrecv(self):
        while True:
            try:
                rev_mes = self.client_socket.recv(10240)
                if rev_mes:
                    data = rev_mes.decode('utf-8')
                    # print(data)
                    self.Q_1.put(data)
                    # self.netsend(self.Q_1.get())
            except:
                break
        print("通讯结束:", self.self_ip, ':', self.send_port)

    def netsend(self, data):
        try:
            self.client_socket.send(data.encode('utf-8'))
        except Exception as e:
            print(f'error! self.client_socket.send:{e}')
        return len(data)

    def stop_Run(self):
        while not self.Q_1.empty():
            print(self.Q_1.get())
        self.server_socket.close()
        self.Q_1.put('exit')
        try:
            self.client_socket.close()
        except:
            print("无连接")



class network_TCP(object):
    def __init__(self, id_addr, port, send_port):
        """
        This is TCP client!
        '192.168.100.243', 8080, 4444/6666/
        :param id_addr: HOST IP
        :param port: HOST port
        :param send_port: Client port
        """
        self.flag = True
        self.Q_1 = Queue(5)
        self.id_addr = id_addr
        self.port = port
        self.send_port = send_port
        self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # self.tcp_socket.bind(('192.168.1.6', send_port))
        self.tcp_socket.bind((self.get_ip_port(), send_port))

        self.tcp_socket.connect((self.id_addr, self.port))

        self.get_mes_Thread = threading.Thread(target=self.netrecv, args=())
        self.get_mes_Thread.start()

    def get_ip_port(self):
        self.self_ip = socket.gethostbyname(socket.gethostname())
        return self.self_ip

    def netrecv(self):
        while self.flag:
            if self.tcp_socket:
                try:
                    rev_mes = self.tcp_socket.recv(10240)
                    if rev_mes:
                        data = rev_mes.decode('utf-8')
                        self.temp_mes = data
                        self.Q_1.put(data)
                except Exception as e:
                    print(f"network error information:{e}")
        print("本地通讯结束:", self.self_ip, ':', self.send_port)

    def netsend(self, data):
        self.tcp_socket.send(data.encode('utf-8'))
        return len(data)

    def stop_Run(self):
        while not self.Q_1.empty():
            print(self.Q_1.get())
        self.flag = False
        self.tcp_socket.shutdown(1)
        self.tcp_socket.close()
        self.Q_1.put('exit')


if __name__ == '__main__':
    UDP_1 = network_UDP(8001, 8001)
